#include <CIpodLibWrapper.h>
#include <CIpodLib.h>
#include <CIpodLog.h>
#include <string.h>
#include "CIpodChip.h"

static CIpodLib *libipod = NULL;

int ipodLibInitFun(int mode ,int connMode)
{
    if(libipod == NULL) {
        CIpodLog::i("ipodLibInitFun libipod = NULL \n");
        return -1;
   }

    return libipod->ipodLibInit(mode,connMode);
}

int ipodLibDeinit()
{
    if(libipod == NULL) return -1;

    libipod->ipodLibDeinit();

    return 0;
}

void registerObserver(IPODObserver* observer)
{
    CIpodLog::i("CIpodLibWrapper registerObserver \n");
    libipod = CIpodLib::getInstance();

    if(observer != NULL){
        libipod->registerObserver(observer);
    }
}

void initialize()
{
    // Cache the certificate at startup since the certificate doesn't change and this saves ~200 ms each time.

    printf("initialize the certificate at startup.\n");
    CIpodChip::MFiPlatform_Initialize();
}

void unregisterObserver()
{
    if(libipod == NULL) return;

    libipod->unregisterObserver();
}

void notifyBtAddress(const uint8 *address)
{
    if(libipod == NULL) return;

    libipod->notifyBtAddress(address);
}

void notifyBtStatus( bool connected)
{
    if(libipod == NULL) return;

    libipod->notifyBtStatus(connected);
}

int iap2Connect(ipod_t * handle, const char *path)
{
    if(libipod == NULL) return -1;

    return libipod->connect(handle, path);
}

int iap2Disconnect(ipod_t * handle)
{
    if(*handle < 0)return 0;

    if(libipod != NULL) libipod->disconnect(handle);

    // unregisterObserver();

    // ipodLibDeinit();
    return 0;
}

int notifyUSBAudioStatus(ipod_t handle, bool enabled)
{
    if(libipod == NULL) return -1;

    return libipod->notifyUSBAudioStatus(handle,enabled);
}

int sendMediaCommand(ipod_t handle, int command)
{
    if(libipod == NULL) return -1;

    return libipod->sendMediaCommand(handle,command);
}

int sendMediaCommandDown(ipod_t handle, int command)
{
    if(libipod == NULL) return -1;

    return libipod->sendMediaCommandDown(handle,command);
}

int sendMediaCommandUp(ipod_t handle, int command)
{
    if(libipod == NULL) return -1;

    return libipod->sendMediaCommandUp(handle,command);
}

int setPlayingTrackPosition(ipod_t handle, uint32 position)
{
    if(libipod == NULL) return -1;

    return libipod->setPlayingTrackPosition(handle,position);
}

int getShuffleMode(ipod_t handle, int *mode)
{
    if(libipod == NULL) return -1;

    return libipod->getShuffleMode(handle,mode);
}

int getRepeatMode(ipod_t handle, int *mode)
{
    if(libipod == NULL) return -1;

    return libipod->getRepeatMode(handle,mode);
}

int getPlayingTrackDuration(ipod_t handle, int * duration)
{
    if(libipod == NULL) return -1;

    return libipod->getPlayingTrackDuration(handle, duration);
}

int getPlayingTrackTitle(ipod_t handle, char *title)
{
    std::string titleTemp;
    std::string buf = "";// default is null
    int result = 0;

    if(libipod != NULL) {
        result = libipod->getPlayingTrackTitle(handle,titleTemp);
        if(result < 0){
            titleTemp = buf;
        }
    }else{
        titleTemp = buf;
    }

    int title_len = titleTemp.size();
    if(title_len > IPOD_TRACK_NAME_MAX_LEN){
        title_len = IPOD_TRACK_NAME_MAX_LEN;
    }
    memcpy(title,titleTemp.c_str(),title_len);

    return 0;
}

int getPlayingTrackAlbum(ipod_t handle, char *album)
{
    std::string albumTemp;
    std::string buf = "";// default is null
    int result = 0;

    if(libipod != NULL) {
        result = libipod->getPlayingTrackAlbum(handle,albumTemp);
        if(result < 0){
            albumTemp = buf;
        }
    }else{
        albumTemp = buf;
    }

    int album_len = albumTemp.size();
    if(album_len > IPOD_TRACK_NAME_MAX_LEN){
        album_len = IPOD_TRACK_NAME_MAX_LEN;
    }
    memcpy(album,albumTemp.c_str(),album_len);

    return 0;
}

int getPlayingTrackArtist(ipod_t handle, char *artist)
{
    std::string artistTemp;
    std::string buf = "";// default is null
    int result = 0;

    if(libipod != NULL) {
        result = libipod->getPlayingTrackArtist(handle,artistTemp);
        if(result < 0){
            artistTemp = buf;
        }
    }else{
        artistTemp = buf;
    }

    int artist_len = artistTemp.size();
    if(artist_len > IPOD_TRACK_NAME_MAX_LEN){
        artist_len = IPOD_TRACK_NAME_MAX_LEN;
    }
    memcpy(artist,artistTemp.c_str(),artist_len);

    return 0;
}

int getPlayingTrackAlbumArtwork(ipod_t handle)
{
    if(libipod == NULL) return -1;

    return libipod->getPlayingTrackAlbumArtwork(handle);
}

int getPlayStatus(ipod_t handle, IPODPlayStatus *status)
{
    if(libipod != NULL)
    {
        libipod->getPlayStatus(handle,status);
    }else{
        status->track_position = 0;
        status->track_length = 0;
        status->state = IPODPlaybackState::STOPPED;
    }
    return 0;
}

int getPlayingTrackInfo( ipod_t handle, int32 *index, uint32 *count)
{
    if(libipod == NULL) return -1;

    return libipod->getPlayingTrackInfo(handle,index,count);
}

int getPlayingChapterInfo(ipod_t handle, int32 *index, uint32 *count)
{
    if(libipod == NULL) return -1;

    return libipod->getPlayingChapterInfo(handle,index,count);
}

int isListLevelSupported(ipod_t handle, bool *supported)
{
    if(libipod == NULL) return -1;

    return libipod->isListLevelSupported(handle,supported);
}

int resetMusicList(ipod_t handle, uint32 *num)
{
    if(libipod == NULL) return -1;
    CIpodLog::i("CIpodLibWrapper resetMusicList \n");

    return libipod->resetMusicList(handle,num);
}

int selectMusicList(ipod_t handle, int32 index, int32 level, uint32 *num)
{
    if(libipod == NULL) return -1;

    return libipod->selectMusicList(handle,index,level,num);
}

int getMusicList_c(ipod_t handle, uint32 startIndex, uint32 readCount, C_IPODMusicList *c_musicList)
{
    if(readCount > IPOD_GET_LIST_MAX_LEN){
        readCount = IPOD_GET_LIST_MAX_LEN;
    }

    if(libipod == NULL) return -1;

    int result = libipod->getMusicList_c(handle, startIndex, readCount,c_musicList);
    if (result < 0) {
        c_musicList->size = 0;
        c_musicList->totalnum = 0;
        c_musicList->start = 0;
        c_musicList->end = 0;
        c_musicList->categorytype = IPODCategoryType::ALL;
    }
    return 0;
}

int selectMusicPlayingList(ipod_t handle, int32 index)
{
    if(libipod == NULL) return -1;

    return libipod->selectMusicPlayingList(handle,index);
}

int getMusicPlayingList(ipod_t handle, uint32 startIndex, uint32 readCount, C_IPODMusicList *c_musicList)
{
    if(readCount > IPOD_GET_LIST_MAX_LEN){
        readCount = IPOD_GET_LIST_MAX_LEN;
    }

    if(libipod == NULL) return -1;

    int result = libipod->getMusicPlayingList(handle, startIndex, readCount,c_musicList);
    if (result < 0) {
        c_musicList->size = 0;
        c_musicList->totalnum = 0;
        c_musicList->start = 0;
        c_musicList->end = 0;
        c_musicList->categorytype = IPODCategoryType::ALL;
    }
    return 0;
}

int launchApp(ipod_t handle, const char *appBundleID)
{
    if(libipod == NULL) return -1;

    return libipod->launchApp(handle,appBundleID);
}

int sendEAData(ipod_t handle, const uint8 *data, uint16 len)
{
    if(libipod == NULL) return -1;

    return libipod->sendEAData(handle,data,len);
}

int getEANativeState(ipod_t handle)
{
    if(libipod == NULL) return -1;

    return libipod->getEANativeState(handle);
}

int setLocationInformation(ipod_t handle, const char *sentence)
{
    if(libipod == NULL) return -1;

    return libipod->setLocationInformation(handle,sentence);
}

int wifiInformationSharing(WifiConfigurationInfo wifi_info)
{
    if(libipod == NULL) return -1;
    CIpodLog::i("wifiInformationSharing \n");

    return libipod->wifiInformationSharing(wifi_info);
}

void ipod_bt_spp_state_change(BtSppState state)
{
    if(libipod == NULL) return;
    libipod->ipod_bt_spp_state_change(state);
}

void ipodRegistBtSppSendData(BtSendData n_bt_spp_send_data)
{
    if(libipod == NULL) return;
    CIpodLog::i("ipodRegistBtSppSendData \n");
    libipod->ipodRegistBtSppSendData(n_bt_spp_send_data);
}

void setWiFiDataCallback( WiFiDataCallback callback )
{
    if( libipod == NULL ) return;
    libipod->setWiFiDataCallback( callback );
}

int ipod_BT_spp_data_pro(ipod_t handle, int cDataLen, const char * pData)
{
    if(libipod == NULL) return -1;
//    CIpodLog::i("CIpodLibWrapper ipod_BT_spp_data_pro handle:%d\n",handle);

    return libipod->ipod_BT_spp_data_pro(handle,cDataLen, pData);
}

int sendWiFiData( ipod_t handle,int cDataLen, const char * pData )
{
    if(libipod == NULL) return -1;

    return libipod->sendWiFiData(handle,cDataLen, pData);
}

int iap2CarPlayStartSession(ipod_t handle, int type)
{
    if(libipod == NULL) return -1;

    return libipod->iap2CarPlayStartSession(handle,type);
}

int iap2OOBBTPairingCompletionInformation(ipod_t handle, int resultCode )
{
    if(libipod == NULL) return -1;

    return libipod->iap2OOBBTPairingCompletionInformation(handle,resultCode);
}

int iap2BluetoothPairingAccessoryInformation(ipod_t handle, const char * inPairingDataP192,const char * inPairingDataP256)
{
    if(libipod == NULL) return -1;

    return libipod->iap2BluetoothPairingAccessoryInformation(handle,inPairingDataP192,inPairingDataP256);
}

int iap2BluetoothPairingStatus( ipod_t handle, int success, const char * cancelReason)
{
    if(libipod == NULL) return -1;

    return libipod->iap2BluetoothPairingStatus(handle,success,cancelReason);
}
